import axios from 'axios'
import { transferData, pbEncrypt } from "@/utils/tools"
import { useElMessage } from "@usehook"
import router from "@/router"
import { baseUrl, publicKey } from "@/utils/constant"
import storeInstance from "@/pinia"
import { until } from '@vueuse/core'

const waitUntilFinished = () => new Promise((resolve) => {
    until(() => !!publicKey.value).toBe(true).then(() => {
        return resolve(true)
    })
})
export const getEncryptionToken = async () => {
    await waitUntilFinished()
    const storageToken = storeInstance.userStore.getUserInfo.token
    if (storageToken) {
        const token = {
            token: storageToken,
            tokenTimestamp: new Date().getTime(),
            currentPath: router.currentRoute.value.path,
            platform: "console"
        }
        return pbEncrypt(JSON.stringify(token))
    } else {
        return false
    }
}

// create an axios instance
const service = axios.create({
    baseURL: baseUrl, // url = base url + request url
    // withCredentials: true, // send cookies when cross-domain requests
    // timeout: 10000, // request timeout
    // timeoutErrorMessage:'TimeOut'
    withCredentials: false
})

// request interceptor
service.interceptors.request.use(
    async config => {
        // do something before request is sent
        //config.headers["Access-Control-Allow-Credentials"] = true
        if (config.url === "/loginfo/getData") return config
        const token = await getEncryptionToken()
        if (token) config.headers["x-token"] = token
        return config
    },
    error => {
        // do something with request error
        console.log('error1:' + error) // for debug
        return Promise.reject(error)
    }
)

// response interceptor
service.interceptors.response.use(
    /**
     * If you want to get http information such as headers or status
     * Please return  response => response
     */

    /**
     * Determine the request status by custom code
     * Here is just an example
     * You can also judge the status by HTTP Status Code
     */
    (response) => {
        const interfaceResponse = response.data.hasOwnProperty("version") || window.location.pathname.startsWith("/interface/")
        const responseCode = response.data.responseCode || 200

        if (responseCode === 500) {
            const message = response.data.message || '请求返回异常'
            if (interfaceResponse) {
                return Promise.resolve(response.data)
            }

            response.data.status = false
            if (!["/login", "/data/sql"].includes(response.config.url)) {
                response.data.message = ""
                useElMessage({
                    message: message,
                    type: 'error',
                    duration: 5 * 1000
                })
            }
            return Promise.resolve(response.data)
        }
        return Promise.resolve(transferData(response.data))
    },
    error => {
        const interfaceResponse = error.response.data.hasOwnProperty("version") || window.location.pathname.startsWith("/interface/")
        let statusCode = error.response ? error.response.status : error.request ? error.request.status : 400;
        const response = error.response
        if (interfaceResponse) {
            return Promise.resolve(response.data)
        } else if (statusCode === 401) {
            storeInstance.userStore.logout()
            setTimeout(() => {
                storeInstance.tagMenuStore.clearTagMenu()
            }, 200)
            return Promise.resolve({ message: '', status: false, responseCode: 401, data: null, totalRecord: 0 })
        } else {
            if (error.code === "ERR_NETWORK") useElMessage.error("网络异常")
            return Promise.reject((response && response.data ? response.data : null) || { cancel: error.name === 'CanceledError', status: false, timeout: (error.message || '').includes("timeout"), networkError: error.code === "ERR_NETWORK" })
        }
    }
)

export default service
